﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using System.Linq.Expressions;
using System.Net;
using System.Xml.Linq;

namespace WeatherWS
{
    public class RssReader : IDisposable
    {
        #region properties

        public List<Item> Items { get; set; }
        public string Url { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }

        #endregion

        #region contructors

        public RssReader()
            : this("", new List<Item>())
        { }


        public RssReader(string feedUrl, List<Item> Items)
        {
            Url = feedUrl;
            this.Items = Items;
        }

        #endregion

        #region methods

        //public static List<RssNews> Read(string url)
        //{
        //    
        //    var webClient = new WebClient();

        //    string result = webClient.DownloadString(url);

        //    XDocument document = XDocument.Parse(result);
        //      //xdocument d = xdocuemnt.Load(uri)
        //    return (from descendant in document.Descendants("item")
        //            select new RssNews()
        //            {
        //                Description = descendant.Element("description").Value,
        //                Title = descendant.Element("title").Value,
        //                PublicationDate = descendant.Element("pubDate").Value
        //            }).ToList();
        //}

        public List<Item> GetRss()
        {
            //check to see if the RssURL is empty
            if (String.IsNullOrEmpty(Url))
                //throw an exception if not provided
                throw new ArgumentException("You must provide a feed URL");

            //start the parsing process
            //XmlReaderSettings setting = new XmlReaderSettings();
            //setting.ProhibitDtd = false;

            using (XmlReader reader = XmlReader.Create(Url))
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(reader);
                
                //read title , des of rss
                ParseDocElements(xmlDoc.SelectSingleNode("//channel"), "title", s => Title = s);
                ParseDocElements(xmlDoc.SelectSingleNode("//channel"), "description", s => Description = s);

                //parse the items of the feed
                ParseRssItems(xmlDoc);

                //return the feed items
                return Items;
            }
        }

        private void ParseRssItems(XmlDocument xmlDoc)
        {
            Items.Clear();
            
            XmlNodeList nodes = xmlDoc.SelectNodes("rss/channel/item");

            foreach (XmlNode node in nodes)
            {
                Item item = new Item();
                ParseDocElements(node, "title", s => item.Title = s);
                ParseDocElements(node, "description", s => item.Description = s);
                ParseDocElements(node, "link", s => item.Link = s);
                ParseDocElements(node, "pubDate", s => item.Date = Convert.ToDateTime(s));
                
                Items.Add(item);
            }
        }

        //dung return hoac delegate hay linq ....
        private void ParseDocElements(XmlNode parent, string xPath, Action<string> property)
        {
            XmlNode node = parent.SelectSingleNode(xPath);
            if (node != null)
                property(node.InnerText);
            else
                property("Unresolvable");
        }

        #endregion

        #region IDisposable Members
        /// <summary>
        /// Performs the disposal.
        /// </summary>
        private bool isDisposed;

        private void Dispose(bool disposing)
        {
            if (disposing && !isDisposed)
            {
                Items.Clear();
                Url = null;
                Title = null;
                Description = null;
            }

            isDisposed = true;
        }

        /// <summary>
        /// Releases the object to the garbage collector
        /// </summary>
        public void Dispose()
        {
            //Dispose(true);    //isDisposed false ?
            
            Items.Clear();
            Url = null;
            Title = null;
            Description = null;

            GC.SuppressFinalize(this);
        }

        #endregion
    }
}